package cn.qingyun.gis.modules.express.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.qingyun.gis.modules.express.entity.ExpressRegionHandle;
import cn.qingyun.gis.modules.express.entity.Point;
import cn.qingyun.gis.modules.express.mapper.ExpressRegionHandleMapper;
import cn.qingyun.gis.modules.express.service.IExpressRegionHandleService;
import cn.qingyun.gis.modules.express.util.GeoTool;
import cn.qingyun.gis.modules.express.util.LocationTool;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.csvreader.CsvWriter;
import com.google.common.collect.Lists;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 快递业务规划数据（处理后） 服务实现类
 * </p>
 *
 * @author miyunguo
 * @since 2023-08-29
 */
@Slf4j
@Service
public class ExpressRegionHandleServiceImpl extends ServiceImpl<ExpressRegionHandleMapper, ExpressRegionHandle> implements IExpressRegionHandleService {
    @Resource
    private ExpressRegionHandleMapper expressRegionHandleMapper;
    @Resource
    private IExpressRegionHandleService iExpressRegionHandleService;

    @Resource
    private HttpServletResponse response;
    @Override
    public void wkt84To02() {
        //获取geometry84字段
        List<ExpressRegionHandle> expressRegionHandles = expressRegionHandleMapper.selectList(
                new QueryWrapper<>());
        int batchSize = 500; //批次
        List<ExpressRegionHandle> recordsBatch = Lists.newArrayList(); //存放批次数据
        int i = 0;
        for(ExpressRegionHandle handle:expressRegionHandles){
            if(ObjectUtil.isNotEmpty(handle.getGeometry84())){
                ExpressRegionHandle expressRegionHandle = new ExpressRegionHandle();
                BeanUtil.copyProperties(handle,expressRegionHandle);
                //进行边界地址 84 -> 02
                String geometry = LocationTool.convertWkts(handle.getGeometry84());
                expressRegionHandle.setGeometry(geometry);
                recordsBatch.add(expressRegionHandle);
                if ((i + 1) % batchSize == 0 || (i + 1) == expressRegionHandles.size()) {
                    iExpressRegionHandleService.updateBatchById(recordsBatch);
                    recordsBatch.clear();
                }
            }
            i++;
            log.debug(String.format("====目前已处理%s条,还剩%s条====", i, expressRegionHandles.size() - i));
        }
    }

    @Override
    public void initCenter() {
        QueryWrapper<ExpressRegionHandle> queryWrapper = new QueryWrapper<>();
        //queryWrapper.lambda().eq(ExpressRegionHandle::getCenterPoint,"");
        List<ExpressRegionHandle> expressRegionHandles = this.list(queryWrapper);
        for(ExpressRegionHandle handle : expressRegionHandles){
            if(ObjectUtil.isNotEmpty(handle.getGeometry())){
                //计算中心点
                Point centerPoint = GeoTool.getCenterPoint(handle.getGeometry());
                log.debug(String.format("%s-计算中心点-%s", handle.getId(), centerPoint));
                handle.setCenterPoint(String.format("POINT(%s %s)",centerPoint.getLon(),centerPoint.getLat()));
            }
        }
        this.updateBatchById(expressRegionHandles);
    }


    @SneakyThrows
    @Override
    public void downloadGridNewCsv() {
        /*List<ExpressRegionHandle> handles = expressRegionHandleMapper.selectList(new QueryWrapper<>());
        BufferedWriter fileWriter = null;
        try {
            fileWriter = new BufferedWriter(new FileWriter("data.csv"));
            fileWriter.write("name,center_point,level,code,parent_code,geometry,geometry84");
            for(ExpressRegionHandle handle:handles){
                String line = String.format("%s,%s,%s,%s,%s,%s,%s",
                        ObjectUtil.isEmpty(handle.getName()) ? "" : handle.getName(),
                        ObjectUtil.isEmpty(handle.getCenterPoint()) ? "" : handle.getCenterPoint(),
                        ObjectUtil.isEmpty(handle.getLevel()) ? "" : handle.getLevel(),
                        ObjectUtil.isEmpty(handle.getCode()) ? "" : handle.getCode(),
                        ObjectUtil.isEmpty(handle.getParentCode()) ? "" : handle.getParentCode(),
                        ObjectUtil.isEmpty(handle.getGeometry()) ? "" : handle.getGeometry(),
                        ObjectUtil.isEmpty(handle.getGeometry84()) ? "" : handle.getGeometry84());
                fileWriter.newLine();
                fileWriter.write(line);
            }
            fileWriter.close();
        } catch (IOException e) {
            throw new RuntimeException("数据导出错误");
        }*/

        response.setContentType("application/csv; charset=utf-8");
        response.setHeader("Content-Disposition", "attachment; filename=" + new String("业务区划数据集.csv".getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
        CsvWriter csvWriter = new CsvWriter(response.getOutputStream(), ',', StandardCharsets.UTF_8);
        String[] fields = {"code", "parent_code", "name", "level", "center_point", "geometry"};
        String[] types = {"string", "string", "string", "string", "string"};
        csvWriter.writeRecord(fields);
        csvWriter.writeRecord(types);
        List<ExpressRegionHandle> districts = this.list();

        QueryWrapper<ExpressRegionHandle> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().inSql(ExpressRegionHandle::getCode, "select code from express_region_handle");
        List<ExpressRegionHandle> wkts = iExpressRegionHandleService.list(queryWrapper);
        Map<String, ExpressRegionHandle> wktMap = wkts.stream().collect(Collectors.toMap(ExpressRegionHandle::getCode, item -> item));

        for (ExpressRegionHandle district : districts) {
            ExpressRegionHandle businessWkt = wktMap.get(district.getCode());
            if (Objects.nonNull(businessWkt)) {
                String[] values = {district.getCode(), district.getParentCode(), district.getName(), district.getLevel(), businessWkt.getCenterPoint(), businessWkt.getGeometry()};
                csvWriter.writeRecord(values);
            }
        }
        log.debug("已成功导出{}条业务规划数据", iExpressRegionHandleService.count());
        csvWriter.close();

    }

    @Override
    public void handleGridNewPointCsv6() {
        //1.获取express_region_handle表中的Geometry字段
        List<ExpressRegionHandle> expressRegionHandles = expressRegionHandleMapper.selectList(new QueryWrapper<>());
        int batchSize = 100; //批次
        List<ExpressRegionHandle> recordsBatch = Lists.newArrayList(); //存放批次数据
        int i = 0;
        for(ExpressRegionHandle handle:expressRegionHandles){
            if(ObjectUtil.isNotEmpty(handle.getGeometry())){
                ExpressRegionHandle expressRegionHandle = new ExpressRegionHandle();
                BeanUtil.copyProperties(handle,expressRegionHandle);
                //将原边界地址经纬度各精确到小数点后6位
                String geometry = LocationTool.convertWktPoint6(handle.getGeometry());
                expressRegionHandle.setGeometry(geometry);
                recordsBatch.add(expressRegionHandle);
                if ((i + 1) % batchSize == 0 || (i + 1) == expressRegionHandles.size()) {
                    this.updateBatchById(recordsBatch);
                    recordsBatch.clear();
                }
                i++;
                System.out.println(geometry);
            }
        }
        log.debug("数据解析成功");
    }
}
